package com.smart.wap.move;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.smart.common.entities.ajax.AjaxResult;
import com.smart.common.entities.constant.SmartConstant;
import com.smart.common.entities.core.BaseSearch;
import com.smart.common.entities.core.Page;
import com.smart.common.entities.enums.SmsScene;
import com.smart.common.entities.file.UploadBody;
import com.smart.common.entities.file.UploadResult;
import com.smart.manager.finance.entities.enums.PayPlatform;
import com.smart.manager.finance.entities.enums.PaymentScene;
import com.smart.manager.finance.repository.ApplyRepository;
import com.smart.manager.member.repository.MemberProfileMainRepository;
import com.smart.manager.pop.entities.assembler.AgentRequest;
import com.smart.manager.pop.entities.body.RDisBill;
import com.smart.manager.pop.entities.enums.RegisterKind;
import com.smart.manager.pop.entities.models.PopActivityMain;
import com.smart.manager.pop.entities.models.PopDisBill;
import com.smart.manager.pop.entities.models.PopDisInviter;
import com.smart.manager.pop.entities.models.PopDisLevel;
import com.smart.manager.pop.entities.models.query.QPopActivityMain;
import com.smart.manager.pop.entities.models.query.QPopBasicLink;
import com.smart.manager.pop.entities.models.query.QPopDisInviter;
import com.smart.manager.pop.repository.DisBillRepository;
import com.smart.manager.pop.repository.DisInviterRepository;
import com.smart.manager.system.repository.ConfigRepository;
import com.smart.manager.wiki.entities.enums.NoticeScope;
import com.smart.manager.wiki.entities.models.WikiIntelNotice;
import com.smart.manager.wiki.entities.models.WikiIntelRemind;
import com.smart.manager.wiki.entities.models.WikiPopHelp;
import com.smart.manager.wiki.entities.repository.IntelNoticeRepository;
import com.smart.manager.wiki.entities.repository.IntelRemindRepository;
import com.smart.manager.wiki.entities.repository.PopHelpRepository;
import com.smart.service.FileService;
import com.smart.service.poster.PosterService;
import com.smart.utils.WorkAcl;
import com.smart.utils.WorkStp;
import com.smart.wap.bodys.BrokerCation;
import com.smart.wap.bodys.PaymentBody;
import com.smart.wap.bodys.WinkBody;
import com.smart.wap.service.PaymentService;
import com.smart.wap.service.WXPayHandler;
import com.smart.wap.service.WebsiteMainService;
import io.lettuce.core.dynamic.annotation.Param;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 会员资料信息接口
 *
 * @author Administrator
 */
@Api(tags = "渠道端-基础数据")
@RestController
@RequestMapping(SmartConstant.WAP_API_PREFIX + "move/main")
@RequiredArgsConstructor
@Log4j2
public class MoveMainController {

    private final WebsiteMainService websiteMainService;
    private final PaymentService paymentService;
    private final WXPayHandler wxPayHandler;
    private final HttpServletRequest servletRequest;
    private final FileService fileService;

    private final ApplyRepository applyRepository;
    private final DisBillRepository billRepository;
    private final PopHelpRepository popHelpRepository;
    private final DisInviterRepository disInviterRepository;
    private final IntelRemindRepository remindRepository;
    private final IntelNoticeRepository intelNoticeRepository;
    private final ConfigRepository configRepository;
    private final DisBillRepository disBillRepository;
    private final PosterService posterService;
    private final MemberProfileMainRepository memberProfileMainRepository;


    /**
     * 手机验证码
     *
     * @param phone 电话
     * @return {@link AjaxResult}<{@link String}>
     */
    @GetMapping("phoneCaptcha/{phone}")
    @ApiOperation(value = "获取手机验证码")
//    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<String> phoneCaptcha(@PathVariable String phone) {
        log.warn(phone);
        Assert.isFalse(StrUtil.isBlank(phone) || phone.equals("null") || phone.equals("undefined"), "手机号不能为空");
        websiteMainService.getSmsCode(SmsScene.POP_REVISE, phone);
        return AjaxResult.success();
    }


    @PostMapping("agentAddUser")
    @ApiOperation("补全个人信息")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<String> agentAddUser(@Validated @RequestBody BrokerCation.AgentInfo body) {
        log.warn(body);
        websiteMainService.AgentAddUser(body);
        return AjaxResult.success();
    }


    @GetMapping(value = "myQr")
    @ApiOperation(value = "我的二维码")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<List<UploadResult>> showQRCode(@Param("type") @Validated Boolean type) {
        PopDisInviter account = websiteMainService.getAccount();
        if (type) {
            return AjaxResult.data(account.getImage());
        }
        return AjaxResult.data(account.getImageUser());
    }


    @GetMapping("delPoster")
    @ApiOperation("删除我的海报")
    public AjaxResult<String> delPoster (@Param("uid")String uid){
        websiteMainService.delPoster(uid);
        return AjaxResult.success();
    }


    /**
     * 海报广场
     *
     * @param type
     * @return {@link AjaxResult}<{@link List}<{@link Map}<{@link String},{@link String}>>>
     */
    @GetMapping(value = "getPostersAll")
    @ApiOperation(value = "查询所有海报")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<List<Map<String, String>>> getPostersAll(@Param("type") @Validated Boolean type) {
        log.warn("getPostersAll == {}", type);
        List<Map<String, String>> all = websiteMainService.getPostersAll(type);
        return AjaxResult.data(all);
    }


    @GetMapping("verification")
    @ApiOperation("验证是否绑定齐全")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<String> verification() {
        String s = websiteMainService.testAndVerify();
        return AjaxResult.data(s);
    }

    @GetMapping("getGrade")
    @ApiOperation("获取购买商品")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<List<PopDisLevel>> getGrade() {
        List<PopDisLevel> grade = websiteMainService.getGrade();
        return AjaxResult.data(grade);
    }



    /**
     * 得到通知url
     *
     * @param payPlatform 支付平台
     * @return {@link String}
     */
    private String getNotifyUrl(PayPlatform payPlatform, String appId) {
        String currentUrl = servletRequest.getRequestURL().toString();
        String platformName = payPlatform.name().toLowerCase();
        String scene = PaymentScene.KEEP.name().toLowerCase();
        String callbackUri = SmartConstant.OTHER_API_PREFIX + "payment/callback/".concat(platformName).concat("/").concat(appId).concat("/").concat(scene);
        return currentUrl.replace("http://", "https://")
                .replace("/wap/move/main/leveOrder", callbackUri);
    }


    @GetMapping("getListHelp")
    @ApiOperation("获取帮助中心")
    public AjaxResult<List<WikiPopHelp>> getListHelp() {
        List<WikiPopHelp> list = popHelpRepository.getList();
        return AjaxResult.data(list);
    }

    /**
     * 代理申请提现
     *
     * @param body 量
     * @return {@link AjaxResult}<{@link String}>
     */
    @ApiOperation(value = "申请提现")
    @PostMapping("withdrawals")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<String> withdrawals(@RequestBody @Validated PaymentBody.AgentTxBody body) {
        Long loginId = WorkAcl.getLoginId();
        applyRepository.add(loginId, body.getAmount());
        return AjaxResult.success();
    }


    /**
     * 查询我的流水/台账
     *
     * @param search 查询条件
     * @return {@link AjaxResult}<{@link List}<{@link PopDisBill}>>
     */
    @GetMapping(value = "streamList")
    @ApiOperation(value = "查询我的流水")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<List<PopDisBill>> streamPageList(@Validated RDisBill.SearchH5 search) {
        Long loginId = WorkAcl.getLoginId();
        log.warn(search);
        List<PopDisBill> popDisBills = billRepository.agentList(loginId, search);
        log.warn(popDisBills);
        return AjaxResult.data(popDisBills);
    }


    /**
     * 排名列表
     *
     * @return {@link AjaxResult}<{@link AgentRequest}>
     */
    @GetMapping("listRanking")
    @ApiOperation("我的排行榜")
    public AjaxResult<AgentRequest.leaderboard> listRanking() {
        AgentRequest.leaderboard agentRequest = disInviterRepository.listRanking();
        return AjaxResult.data(agentRequest);
    }


    /**
     * 我获取用户团队
     * 拉人列表
     * 查询我的团队信息
     *
     * @return {@link AjaxResult}<{@link AgentRequest.myUserTeam}>
     */
    @GetMapping(value = "getUserTeam")
    @ApiOperation(value = "查询我的用户团队信息")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<AgentRequest.myUserTeam> getUserTeam() {
        Long loginId = WorkAcl.getLoginId();
        AgentRequest.myUserTeam myUserTeam = disInviterRepository.UserList(loginId);
        return AjaxResult.data(myUserTeam);
    }

    /**
     * 得到团队
     * 拉人列表
     * 查询我的团队信息
     *
     * @return {@link AjaxResult}<{@link AgentRequest.myTeam}>
     */
    @GetMapping(value = "getTeam")
    @ApiOperation(value = "查询我的代理团队信息")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<AgentRequest.myTeam> getTeam() {
        Long loginId = WorkAcl.getLoginId();
        AgentRequest.myTeam myTeam = disInviterRepository.AgentUserList(loginId);
        return AjaxResult.data(myTeam);
    }


    /**
     * 在H5上BASE64上传图片
     *
     * @param dto dto
     * @return {@code AjaxResult}
     */
    @PostMapping("base64-image-h5")
    @ApiOperation(value = "H5__BASE64上传图片")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<UploadResult> uploadImageH5ByBase64(@RequestBody @Validated UploadBody.Base64 dto) {
        UploadResult uploadResult = fileService.uploadFile(dto, "", "", true);
        Assert.notNull(uploadResult.getUrl(), "上传数据异常");
        new QPopDisInviter().id.eq(WorkAcl.getLoginId()).setMaxRows(1).findOne().setQrPay(uploadResult.getUrl()).update();
        return AjaxResult.data(uploadResult);
    }


    @GetMapping(value = "remind/list")
    @ApiOperation(value = "获取消息提醒")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<Page<WikiIntelRemind>> remindList() {
        WinkBody.RemindSearchBody searchBody = new WinkBody.RemindSearchBody();
        searchBody.setPageNo(1);
        searchBody.setPageSize(50);
        searchBody.setFilterRead(false);
        Page<WikiIntelRemind> result = remindRepository.getPageList(NoticeScope.CHANNEL, WorkAcl.getLoginId(), searchBody);
        return AjaxResult.data(result);
    }

    @GetMapping(value = "notice/list")
    @ApiOperation(value = "系统通知列表")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<Page<WikiIntelNotice>> noticeList() {
        BaseSearch searchBody = new BaseSearch();
        searchBody.setPageNo(1);
        searchBody.setPageSize(50);
        Page<WikiIntelNotice> result = intelNoticeRepository.getPageList(NoticeScope.CHANNEL, WorkAcl.getLoginId(), searchBody);
        return AjaxResult.data(result);
    }

    @GetMapping(value = "remind/oneKeyRead")
    @ApiOperation(value = "提醒一键已读")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<String> oneKeyRead() {
        int i = remindRepository.oneKeyToRead(NoticeScope.MEMBER, WorkAcl.getLoginId());
        return AjaxResult.success(String.format("成功设置%s条提醒消息为已读", i));
    }


    @GetMapping(value = "getConfig")
    @ApiOperation(value = "获取配置文件")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<JSONObject> getConfig() {
        JSONObject kefu = configRepository.readCache("Kefu");
        JSONObject YongJin = configRepository.readCache("YongJin");
        kefu.putAll(YongJin);
        return AjaxResult.data(kefu);
    }

    @GetMapping(value = "getDay")
    @ApiOperation(value = "获取当日受益")
    @SaCheckLogin(type = WorkStp.TYPE)
    public AjaxResult<BigDecimal> getDay() {
        BigDecimal day = disBillRepository.getDay(WorkAcl.getLoginId());
        return AjaxResult.data(day);
    }

    @GetMapping(value = "createMaterial")
    @ApiOperation(value = "上传合成后素材")
    public AjaxResult<UploadResult> createMaterial(@Param("uid") @Validated Long uid) {
        PopDisInviter inviter = disInviterRepository.getOneById(WorkAcl.getLoginId());
        // 代理 + acting   用户 + uid
        PopActivityMain one = new QPopActivityMain().kind.ne(RegisterKind.C2C).posterId.eq(uid).setMaxRows(1).findOne();
        Assert.notNull(one, "未找到海报!");
        String attribute = new QPopBasicLink().id.eq(one.getLinkId()).select(QPopBasicLink.Alias.url).findSingleAttribute();

        if (CollUtil.isEmpty(inviter.getImage())){
            inviter.setImage(new ArrayList<>());
        }
        if (one.getKind().equals(RegisterKind.B2B)) {
            long count = inviter.getImage().stream().filter(x -> x.getUid().equals(String.valueOf(uid))).count();
            Assert.isFalse(count > 0, "当前海报已经添加过了");
        }else {
            long count = inviter.getImageUser().stream().filter(x -> x.getUid().equals(String.valueOf(uid))).count();
            Assert.isFalse(count > 0, "当前海报已经添加过了");
        }

        String url = attribute.concat("?inviteCode=").concat(String.valueOf(inviter.getId()));
        if (one.getKind().equals(RegisterKind.B2B)){
            url = attribute.concat("?acting=").concat(String.valueOf(inviter.getId()));
        }
        log.warn("生成的地址是 {}",url);
        UploadResult uploadResult = posterService.makePosterImage(uid, url, inviter);
        uploadResult.setName(one.getTitle());
        uploadResult.setUid(String.valueOf(uid));
        if (one.getKind().equals(RegisterKind.B2B)) {
            inviter.setImage(addImage(inviter.getImage(),uploadResult)).update();
        } else {
            inviter.setImageUser(addImage(inviter.getImageUser(),uploadResult)).update();
        }
        inviter.update();
        return AjaxResult.data(uploadResult);
    }



    @GetMapping("getAgentOne")
    @ApiOperation("获取代理的个人信息")
    public AjaxResult<Map<String,Object>> getAgentOne(@Param("uid")Long uid){
        log.warn(uid);
        PopDisInviter inviter = disInviterRepository.getOneById(uid);
        Map<String, Object> map = Map.of("name", inviter.getRealName(), "avatar", inviter.getAvatar(), "id", inviter.getId(), "phone", DesensitizedUtil.mobilePhone(inviter.getPhone()));
        return AjaxResult.data(map);
    }

    public List<UploadResult> addImage(List<UploadResult> img, UploadResult uploadResult) {

        if (CollUtil.isNotEmpty(img)) {
            img.add(uploadResult);
            return img;
        }
        List<UploadResult> results = new ArrayList<>();
        results.add(uploadResult);
        return results;
    }

}
